package org.jeecg.modules.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.common.util.PasswordUtil;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.modules.system.entity.SysEmployee;
import org.jeecg.modules.system.entity.SysUserDepart;
import org.jeecg.modules.system.mapper.SysEmployeeMapper;
import org.jeecg.modules.system.service.ISysEmployeeService;
import org.jeecg.modules.system.service.ISysUserDepartService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

/**
 * 员工信息表 服务实现类
 */
@Service
@Slf4j
public class SysEmployeeServiceImpl extends ServiceImpl<SysEmployeeMapper, SysEmployee> implements ISysEmployeeService {

    @Resource
    private SysEmployeeMapper sysEmployeeMapper;

    @Resource
    private ISysUserDepartService sysUserDepartService;

    @Override
    public IPage<SysEmployee> getEmployeePageList(Page<SysEmployee> page, SysEmployee employee) {
        // 获取请求中的部门IDs参数
        String departIds = null;
        try {
            // 尝试从RequestContextHolder获取当前请求
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            if (request != null) {
                departIds = (String) request.getAttribute("departIds");
            }
        } catch (Exception e) {
            log.warn("获取请求上下文失败", e);
        }
        
        // 调用Mapper方法，传递部门IDs参数
        return sysEmployeeMapper.getEmployeePageList(page, employee, departIds);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addEmployee(SysEmployee employee) {
        // 检查员工编号唯一性
        if (StringUtils.isNotBlank(employee.getEmpNo()) && checkEmpNoExists(employee.getEmpNo(), null)) {
            throw new RuntimeException("员工编号已存在");
        } else if (StringUtils.isBlank(employee.getEmpNo())) {
            // 自动生成员工编号：当前租户ID + 员工编号自增
            Integer tenantId = employee.getTenantId();
            if (tenantId == null) {
                // 如果没有租户ID，尝试从TenantContext获取
                try {
                    String tenantIdStr = TenantContext.getTenant();
                    if (StringUtils.isNotBlank(tenantIdStr)) {
                        tenantId = Integer.parseInt(tenantIdStr);
                        employee.setTenantId(tenantId);
                    } else {
                        tenantId = 0; // 默认租户ID
                    }
                } catch (Exception e) {
                    log.warn("获取租户ID失败", e);
                    tenantId = 0; // 默认租户ID
                }
            }
            
            // 获取当前租户下最大的员工编号
            String maxEmpNo = sysEmployeeMapper.getMaxEmpNoByTenantId(tenantId);
            int sequence = 1;
            if (maxEmpNo != null && maxEmpNo.length() > String.valueOf(tenantId).length()) {
                try {
                    String sequenceStr = maxEmpNo.substring(String.valueOf(tenantId).length());
                    // 如果包含分隔符，需要去除
                    if (sequenceStr.startsWith("-")) {
                        sequenceStr = sequenceStr.substring(1);
                    }
                    if (StringUtils.isNotBlank(sequenceStr)) {
                        sequence = Integer.parseInt(sequenceStr) + 1;
                    }
                } catch (NumberFormatException e) {
                    log.warn("解析员工编号序列失败", e);
                }
            }
            
            // 生成新的员工编号
            employee.setEmpNo(tenantId + "-"+ String.format("%06d", sequence));
        }
        
        // 设置默认工作状态
        if (employee.getWorkStatus() == null) {
            employee.setWorkStatus(1); // 默认在职状态
        }
        
        // 处理登录账号和密码
        if (StringUtils.isNotBlank(employee.getUsername())) {
            // 验证登录账号是否是手机号
            if (!employee.getUsername().matches("^1[3456789]\\d{9}$")) {
                throw new RuntimeException("登录账号必须是有效的手机号码");
            }
            
            // 如果提供了登录账号，检查是否已存在
            LambdaQueryWrapper<SysEmployee> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysEmployee::getUsername, employee.getUsername());
            if (this.count(queryWrapper) > 0) {
                throw new RuntimeException("登录账号已存在");
            }
        } else if (StringUtils.isNotBlank(employee.getPhone())) {
            // 如果没有提供登录账号，但提供了手机号，使用手机号作为默认登录账号
            // 首先验证手机号格式
            if (!employee.getPhone().matches("^1[3456789]\\d{9}$")) {
                throw new RuntimeException("手机号格式不正确，无法用作登录账号");
            }
            
            // 检查手机号是否已被用作登录账号
            LambdaQueryWrapper<SysEmployee> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysEmployee::getUsername, employee.getPhone());
            if (this.count(queryWrapper) > 0) {
                throw new RuntimeException("该手机号已被用作其他员工的登录账号");
            }
            
            employee.setUsername(employee.getPhone());
        } else {
            // 如果既没有登录账号也没有手机号，使用员工编号作为默认登录账号
            employee.setUsername(employee.getEmpNo());
        }
        
        // 处理密码
        if (StringUtils.isBlank(employee.getPassword())) {
            // 如果没有提供密码，使用员工编号作为默认密码
            String salt = oConvertUtils.randomGen(8);
            employee.setSalt(salt);
            String defaultPassword = PasswordUtil.encrypt(employee.getUsername(), employee.getEmpNo(), salt);
            employee.setPassword(defaultPassword);
        } else {
            // 如果提供了密码，进行加密处理
            String salt = oConvertUtils.randomGen(8);
            employee.setSalt(salt);
            String encryptedPassword = PasswordUtil.encrypt(employee.getUsername(), employee.getPassword(), salt);
            employee.setPassword(encryptedPassword);
        }
        
        // 设置创建人和创建时间
        String username = "admin";
        try {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (sysUser != null) {
                username = sysUser.getUsername();
            }
        } catch (Exception e) {
            log.warn("获取登录用户信息失败", e);
        }
        employee.setCreateBy(username);
        employee.setCreateTime(new Date());
        
        return this.save(employee);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean editEmployee(SysEmployee employee) {
        // 检查员工编号唯一性
        if (StringUtils.isNotBlank(employee.getEmpNo()) && checkEmpNoExists(employee.getEmpNo(), employee.getId())) {
            throw new RuntimeException("员工编号已存在");
        }
        
        // 获取原始数据
        SysEmployee oldEmployee = this.getById(employee.getId());
        if (oldEmployee == null) {
            throw new RuntimeException("员工不存在");
        }
        
        // 处理登录账号
        if (StringUtils.isNotBlank(employee.getUsername()) && !employee.getUsername().equals(oldEmployee.getUsername())) {
            // 验证登录账号是否是手机号
            if (!employee.getUsername().matches("^1[3456789]\\d{9}$")) {
                throw new RuntimeException("登录账号必须是有效的手机号码");
            }
            
            // 如果修改了登录账号，检查是否已存在
            LambdaQueryWrapper<SysEmployee> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysEmployee::getUsername, employee.getUsername())
                    .ne(SysEmployee::getId, employee.getId());
            if (this.count(queryWrapper) > 0) {
                throw new RuntimeException("登录账号已存在");
            }
        }
        
        // 如果更新了手机号但没有更新登录账号，且原来的登录账号与原手机号相同，则自动更新登录账号
        if (StringUtils.isNotBlank(employee.getPhone()) && 
            !employee.getPhone().equals(oldEmployee.getPhone()) && 
            oldEmployee.getUsername().equals(oldEmployee.getPhone())) {
            
            // 检查新手机号是否已被用作登录账号
            LambdaQueryWrapper<SysEmployee> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysEmployee::getUsername, employee.getPhone())
                     .ne(SysEmployee::getId, employee.getId());
            if (this.count(queryWrapper) > 0) {
                throw new RuntimeException("该手机号已被用作其他员工的登录账号");
            }
            
            // 更新登录账号为新手机号
            employee.setUsername(employee.getPhone());
        }
        
        // 处理密码
        if (StringUtils.isNotBlank(employee.getPassword())) {
            // 如果提供了新密码，进行加密处理
            String salt = oConvertUtils.randomGen(8);
            employee.setSalt(salt);
            String encryptedPassword = PasswordUtil.encrypt(employee.getUsername(), employee.getPassword(), salt);
            employee.setPassword(encryptedPassword);
        } else {
            // 如果没有提供密码，保持原密码不变
            employee.setPassword(oldEmployee.getPassword());
            employee.setSalt(oldEmployee.getSalt());
        }
        
        // 设置更新人和更新时间
        String username = "admin";
        try {
            LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            if (sysUser != null) {
                username = sysUser.getUsername();
            }
        } catch (Exception e) {
            log.warn("获取登录用户信息失败", e);
        }
        employee.setUpdateBy(username);
        employee.setUpdateTime(new Date());
        
        return this.updateById(employee);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteEmployee(String id) {
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatchEmployee(String[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }

    @Override
    public SysEmployee getEmployeeByEmpNo(String empNo) {
        if (StringUtils.isBlank(empNo)) {
            return null;
        }
        return sysEmployeeMapper.getEmployeeByEmpNo(empNo);
    }

    @Override
    public SysEmployee getEmployeeByUsername(String username) {
        if (StringUtils.isBlank(username)) {
            return null;
        }
        return sysEmployeeMapper.getEmployeeByUsername(username);
    }

    @Override
    public boolean checkEmpNoExists(String empNo, String id) {
        if (StringUtils.isBlank(empNo)) {
            return false;
        }
        LambdaQueryWrapper<SysEmployee> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysEmployee::getEmpNo, empNo);
        if (StringUtils.isNotBlank(id)) {
            queryWrapper.ne(SysEmployee::getId, id);
        }
        return this.count(queryWrapper) > 0;
    }

    @Override
    public boolean checkDepartHasEmployee(String departId) {
        Integer count = sysEmployeeMapper.countEmployeeByDepartId(departId);
        return count != null && count > 0;
    }

    @Override
    public SysEmployee checkEmployeeLogin(String username, String password, Integer tenantId) {
        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
            return null;
        }
        
        // 构建查询条件
        LambdaQueryWrapper<SysEmployee> queryWrapper = new LambdaQueryWrapper<>();
        // 同时支持使用empNo或username登录
        queryWrapper.and(wrapper -> wrapper.eq(SysEmployee::getUsername, username)
                                           .or()
                                           .eq(SysEmployee::getEmpNo, username));
        
        // 如果有租户ID，添加租户条件
        if (tenantId != null) {
            queryWrapper.eq(SysEmployee::getTenantId, tenantId);
        }
        
        // 只查询在职员工
        queryWrapper.eq(SysEmployee::getWorkStatus, 1);
        
        // 查询员工信息
        SysEmployee employee = getOne(queryWrapper);
        
        if (employee == null) {
            return null;
        }
        // 判断密码是否为空，为空则使用默认密码（员工编号）
        if (StringUtils.isBlank(employee.getPassword())) {
            // 使用员工编号作为默认密码
            String defaultPassword = PasswordUtil.encrypt(employee.getUsername(), employee.getUsername(), employee.getSalt());
            employee.setPassword(defaultPassword);
            // 更新到数据库
            updateById(employee);
        }
        
        // 校验密码
        String encryptedPassword = PasswordUtil.encrypt(employee.getUsername(), password, employee.getSalt());
        if (!encryptedPassword.equals(employee.getPassword())) {
            return null;
        }
        
        return employee;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateEmployeePassword(String empId, String newPassword) {
        if (StringUtils.isBlank(empId) || StringUtils.isBlank(newPassword)) {
            return false;
        }
        
        // 查询员工信息
        SysEmployee employee = getById(empId);
        if (employee == null) {
            return false;
        }
        
        // 加密新密码
        String encryptedPassword = PasswordUtil.encrypt(employee.getEmpNo(), newPassword, employee.getSalt());
        
        // 更新密码
        employee.setPassword(encryptedPassword);
        
        return updateById(employee);
    }

    @Override
    public IPage<SysEmployee> getEmployeeByRoleId(Page<SysEmployee> page, String roleId, String empNo) {
        // 参数校验
        if (StringUtils.isBlank(roleId)) {
            return new Page<>();
        }
        
        // 调用Mapper查询员工列表
        return sysEmployeeMapper.getEmployeeByRoleId(page, roleId, empNo);
    }
} 